/*******************************************************************************
 * Copyright (c) 2008 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Sylvain Sicard - initial API and implementation
 ******************************************************************************/
package fr.jade.fraclite.orb.registry;

import java.util.HashMap;
import java.util.Map;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.control.LifeCycleController;
import org.objectweb.naming.Binder;

import fr.jade.fraclite.api.ComponentInterface;
import fr.jade.fraclite.api.control.GenericAttributeController;
import fr.jade.fraclite.api.control.NoSuchAttributeException;

/**
 * 
 * @author ssicard
 */
public class BasicNamingService implements NamingService, GenericAttributeController, LifeCycleController, BindingController {

  Component self = null;
  
  // Attributes
  protected static final String portAttName   = "port";
  protected int                 port          = 0;

  final static String[]         attList       = { portAttName };

  protected boolean initialized = false;
  protected void init() throws Exception{
    if(!initialized){
      Binder binder = Registry.createBinder();
      Map<String, String> context = new HashMap<String, String>();
      context.put("port", String.valueOf(port));
      binder.export(self.getFcInterface("registry"), context);
      initialized = true;
    }
  }
  
  // GenericAttributeController
  public String getAttribute(String name) throws NoSuchAttributeException {
    if (name.equals(portAttName)){
      return String.valueOf(port);
    }else{
      throw new NoSuchAttributeException(name);
    }
  }

  public void setAttribute(String name, String value) throws NoSuchAttributeException {
    if (name.equals(portAttName)){
      port = new Integer(value).intValue();
    }else{
      throw new NoSuchAttributeException(name);
    }
  }

  public String[] listFcAtt() {
    return attList;
  }

  // LifeCycleController
  protected boolean started = false;
  public String getFcState() {
    return started?LifeCycleController.STARTED:LifeCycleController.STOPPED;
  }

  public void startFc() throws IllegalLifeCycleException {
    try {
      init();
    } catch (Exception e) {
      e.printStackTrace();
      throw new IllegalLifeCycleException("Cannot export NamingService interface "+e.toString());
    }
  }

  public void stopFc() throws IllegalLifeCycleException {
  }
  
  // --------------------------------------------------------------------------
  // Implementation of the NamingService interface
  // --------------------------------------------------------------------------

  private Map<String, Component> bindings = new HashMap<String, Component>();

  public synchronized String[] list() {
    return (String[]) bindings.keySet().toArray(new String[bindings.size()]);
  }

  public synchronized Component lookup(final String name) {
    return (Component) bindings.get(name);
  }

  public synchronized boolean bind(final String name, final Component comp) {
    if (!bindings.containsKey(name)) {
      bindings.put(name, comp);
      return true;
    } else {
      return false;
    }
  }

  public synchronized Component rebind(final String name, final Component comp) {
    Component old = (Component) bindings.remove(name);
    bindings.put(name, comp);
    return old;
  }

  public synchronized Component unbind(final String name) {
    return (Component) bindings.remove(name);
  }

  
  // BindingController
  
  public void bindFc(String clientItfName, Object serverItf) throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
    if(clientItfName.equals("component")){
      self = (Component)serverItf;
      ((ComponentInterface)self.getFcInterface("registry")).setFcItfGUId(0);
    }else{
      throw new NoSuchInterfaceException(clientItfName);
    }
  }

  public String[] listFc() {
    return new String[]{};
  }

  public Object lookupFc(String clientItfName) throws NoSuchInterfaceException {
    throw new NoSuchInterfaceException(clientItfName);
  }

  public void unbindFc(String clientItfName) throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
    throw new NoSuchInterfaceException(clientItfName);
  }

}
